package com.miniserver.util;

import java.security.Key;

import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
/**
 * bkdr哈希码 desecb工具类
 * @author PC
 *
 */
public class HashUtility {

	private static final String ALGORITHM_DES = "DESede/ECB/PKCS5Padding";
	/**
	 * 获取bkdr哈希吗
	 * @param key
	 * @return
	 */
	public static Long getBKDRKey(String key) {

		long hash = 0;
		try {
			byte[] md = key.getBytes("UTF-8");
			long seed = 131; // 31 131 1313 13131 131313 etc..
			for (int i = 0; i < md.length; i++) {
				hash = hash * seed + md[i];
			}

			if (hash < 0) {
				hash *= (-1);
			}
		} catch (Exception ex) {
		}
		return Long.valueOf(hash);
	}

	/**
	 * ECB加密,不要IV
	 * 
	 * @param key
	 *            密钥
	 * @param data
	 *            明文
	 * @return Base64编码的密文
	 * @throws Exception
	 */
	public static String encode(String key, String data) throws Exception {
		Key deskey = null;
		DESedeKeySpec spec = new DESedeKeySpec(key.getBytes());
		SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
		deskey = keyfactory.generateSecret(spec);
		Cipher cipher = Cipher.getInstance(ALGORITHM_DES);
		cipher.init(Cipher.ENCRYPT_MODE, deskey);
		byte[] bytes = cipher.doFinal(data.getBytes("UTF-8"));
		return bytesToHexString(bytes);
	}

	/**
	 * ECB解密,不要IV
	 * 
	 * @param key
	 *            密钥
	 * @param data
	 *            Base64编码的密文
	 * @return 明文
	 * @throws Exception
	 */	
	public static String decode(String key, String hexString) throws Exception {
		Key deskey = null;
		DESedeKeySpec spec = new DESedeKeySpec(key.getBytes());
		SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
		deskey = keyfactory.generateSecret(spec);
		Cipher cipher = Cipher.getInstance(ALGORITHM_DES);
		cipher.init(Cipher.DECRYPT_MODE, deskey);		
		byte[] bytes = cipher.doFinal(hexStringToBytes(hexString));
		return new String(bytes, "UTF-8");

	}
	/**
	 * 字节转16进制字符串
	 * @param b
	 * @return
	 */
	public static String bytesToHexString(byte[] b) {
		StringBuilder buffer = new StringBuilder();
		for (int i = 0; i < b.length; i++) {
			String hex = Integer.toHexString(b[i] & 0xFF);
			if (hex.length() == 1) {
				buffer.append('0').append(hex);
			} else
				buffer.append(hex);
		}
		return buffer.toString();
	}
	/**
	 *
	 * @param hexString
	 * @return
	 */
	public static byte[] hexStringToBytes(String hexString) {
		if (hexString == null || hexString.equals("")) {
			return null;
		}
		hexString = hexString.toUpperCase();
		int length = hexString.length() / 2;
		char[] hexChars = hexString.toCharArray();
		byte[] d = new byte[length];
		for (int i = 0; i < length; i++) {
			int pos = i * 2;
			d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));

		}
		return d;
	}

	private static byte charToByte(char c) {
		return (byte) "0123456789ABCDEF".indexOf(c);
	}

	/**
	 * test
	 * 
	 * @param key
	 *            : 12345678
	 */
	public static void main(String[] args) throws Exception {
		try {
			String key="oDXpiGiu$2vcedFnisADGwfV";
			String word="res=320x480&format=xml&storeid=10&size=1&name=大男童科比系列羽绒夹克&quantity=1&endtime=20140805175330&productid=1211020156569620000&price=1299.00";
			System.out.println(encode(key,word));
			System.out.println("7e78d1849f0fef92ee1cf677ea424e50e7e2723cfb04cd75f7fced442ca990e49d072e46995c91ac4f1e5cd54d1f286130aedc5c454148228dc9e89f10eae1f3b6e50718c3fee002bc72befd763f4d579d3ff87a313dcd42f500944c854365d8f267399fca7cafcf59435f5fd6b86e8de7f1c88ccbd464504a2f7ec9bdd563aa607773dfaa0dea2c7290cbd62b87d305da63c79c2cacfb6fa4010015ef9362c4");
		
					System.out.println("明：uid=5 ；密："
					+ HashUtility.encode("IMMyyI2q$yUeTH.DBuckso0N", "uid=5"));
			System.out.println("明：uid=5 ；密："
					+ HashUtility.decode("IMMyyI2q$yUeTH.DBuckso0N",
							HashUtility.encode("IMMyyI2q$yUeTH.DBuckso0N",
									"uid=5")));
			System.out.println("明：uid=5 ；密："
					+ HashUtility.decode("ImMyyI2q$yUeTH.DBuckso0N",
							HashUtility.encode("IMMyyI2q$yUeTH.DBuckso0N",
									"uid=5")));
		} catch (Exception e) {
			System.out.println(e);
		}
	}
	/**
	 * 获取bkdr哈希吗
	 * @param key
	 * @return
	 */
	public static long getBKDRKey(StringBuilder buffer) {
		long hash = 0;
		try {			
			byte[] md =buffer.toString().getBytes("UTF-8");
			long seed = 131; // 31 131 1313 13131 131313 etc..
			for (int i = 0; i < md.length; i++) {
				hash = hash * seed + md[i];
			}
			if (hash < 0) {
				hash *= (-1);
			}
		} catch (Exception ex) {
		}
		return Long.valueOf(hash);
	}
}
